/**
knihovna interpretu
29.11.2011
RA
**/

#ifndef INTERP_H
#define INTERP_H

#include <stdbool.h>
#include "ilist.h"
#include "hash.h"

typedef enum vartype {

  vard = 0,
  varc,
  varb,
  varn
} VType;

typedef struct varTable{
    char* varName;
    double intVal;
    char* charVal;
    bool boolVal;
    struct intCache *varNext;
} *variab;

typedef struct intTable {
    variab varCache;
    char*   FName;
    struct intTable *fNext;
    tInstructionPtr retLabel;
} *interCache;

typedef struct {
    variab Act;
    variab First;
} inIList;

typedef struct {
    interCache Act;
    interCache First;
} inFList;

typedef struct fcTable {
  char* name;
  tInstructionPtr label;
  struct fcTable *fcNext;
} *fcLabels;

typedef struct {
    fcLabels Act;
    fcLabels First;
} inLabels;

inLabels LABLIST;
inIList VARLIST;
inFList FCLIST;
double DNULL = -1;


static void EXsearch(inIList *, char *);
static void initCACHE(inFList *);
static void initVCACHE(inIList *);
static void initLCACHE(inLabels *);
static interCache makeFLIST(char *, inFList *);
static fcLabels makeLLIST(char *, inLabels *, tIList *);
static void write(inIList *, char *);
static void read(inIList *, char *, enumSTypes rtype, int);
static void IN_add(inIList *, char *, char *, char *);
static void IN_sub(inIList *, char *, char *, char *);
static void IN_mul(inIList *, char *, char *, char *);
static void IN_div(inIList *, char *, char *, char *);
static void IN_neg(inIList *, char *, char *);
static void IN_less(inIList *, char *, char *, char *);
static void IN_lesseq(inIList *, char *, char *, char *);
static void IN_grt(inIList *, char *, char *, char *);
static void IN_grteq(inIList *, char *, char *, char *);
static void IN_genvar(inFList *, inIList *, char *);
static void IN_movC(inIList *, char *, char *);
static void IN_movD(inIList *, char *, double);
static void IN_movB(inIList *, char *, bool);
static void IN_conc(inIList *, char *, char *);
static void IN_addchar(inIList *, char *, char *);
static void IN_eq(inIList *, char *, char *, char *);
static void IN_neq(inIList *, char *, char *, char *);
static char *IN_type(inIList *, char *);
static char *IN_substr(inIList *, char *, int, int);
static void IN_POWA(inIList *, char *, int);
static void IN_ret(inFList *, inIList *, char *);
static void IN_disposeIL(inIList *);
static VType IN_vartype(inIList *, char *);
static void IN_disfnc(inFList *, inIList *, char *);
static char *IN_goto(inIList *, char *, char *);
static void INTERPRET(tIList *);

#endif

